/**
 * 
 */
package cl.hhha.web.util;

import java.util.Collection;
import java.util.Date;

import org.apache.log4j.Logger;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Esta clase provee utilidades de validación
 * @author Óscar Álvarez V
 * @email oialvarez@gmail.com
 * @Version 1.0
 * @date 25-06-2009 16:29:58
 */
public class ValidaUtil {
	protected static Logger logger = Logger.getLogger(ValidaUtil.class);

	/**
	 * Valida si un rut es válido.
	 * @param rut El rut a validar
	 * @param dv su dígito verificador
	 * @return verdadero si el dígito verificador, corresponde al rut.
	 */
	public static Boolean isValidRut(String rut, String dv){
		return isEqualsDigits(getDv(rut), dv);
	}
	
	public static Boolean isValidRut(Integer rut, String dv){
		String sRut = null;
		if(rut != null){
			sRut = rut.toString();
		}
		return isEqualsDigits(getDv(sRut), dv);
	}

	/**
	 * Obtiene el digito verificador de un rut.
	 * @param sRut El rut a para comprobar.
	 * @return iDig El digito verificador o -1 si no se puede determinar.
	 */
	public static String getDv(String sRut){
		if(isEmpty(sRut)){
			return "-1";
		}
		try{
			Integer.valueOf(sRut);
		} catch (NumberFormatException nfe) {
			return "-1";
		}

		Integer iCiclo,iMult =2,iSuma=0;
		Integer iLargo = sRut.length();
		String sDig;

		for(iCiclo= iLargo-1;iCiclo>=0;iCiclo--){
			iSuma =(Integer.parseInt(sRut.substring(iCiclo,iCiclo+1)) * iMult)+iSuma;
			iMult++;
			if(iMult==8) iMult =2;
		}

		Integer iDig = 11 - (iSuma % 11);
		switch(iDig){
		case 11 : sDig = "0";break;
		case 10 : sDig ="k";break;
		default : sDig =String.valueOf(iDig);
		}
		return sDig;
	} 

	/**
	 * Determina si dos string son iguales... 
	 * NOTA: si ambos son nulos entonces son iguales.
	 * @param sDv
	 * @param sDig
	 * @return true, si son iguales
	 */
	public static boolean isEqualsDigits(String sDv, String sDig){
		return isNull(sDv) ? isNull(sDig) : sDv.equals(sDig);
	}
	/**
	 * Metodo que valida si una cadena o una coleccion esta vacia.
	 * @param o
	 * @return true, si el objeto es nulo, es una cadena vacia ("") o una coleccion vacia.
	 */
	public static boolean isEmpty(Object o) {
		if(isNull(o)){
			return true;
		}
		if(o instanceof String){
			return "".equals(((String)o).trim());
		}
		if(o instanceof Collection<?>){
			return ((Collection<?>)o).isEmpty();
		}
		return false;
	}

	/**Metodo encargado de validar si el objeto es nulo
	 * 
	 * @param o 
	 * @return
	 */
	public static boolean isNull(Object o) {
		return o == null;
	}

	/**Metodo encargado de verificar que fecha  Vencimiento sea mayor que fecha creacion
	 * 
	 * @param fechaCreacion
	 * @param fechaVencimiento
	 * @return true si fecha vencimiento es mayor o igual a fechaCreacion, sino retorna false
	 */
	public static boolean isDateGreaterOrEqual(Date fechaCreacion, Date fechaVencimiento){
		if(isNull(fechaCreacion)||isNull(fechaVencimiento)){
			return false;
		}
		return fechaCreacion.compareTo(fechaVencimiento)<0;
	}

	/**
	 * metodo para validar correo electronio
	 * @param eMail
	 * @return true, si el correo es valido
	 */
	public static boolean isEmail(String eMail) {
		
		if(isEmpty(eMail)){
			return false;
		}
		
		Pattern pat = null;
		Matcher mat = null;        
		//pat = Pattern.compile("^([0-9a-zA-Z]([_.w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-w]*[0-9a-zA-Z].)+([a-zA-Z]{2,9}.)+[a-zA-Z]{2,3})$");
		
		//patron tomado de http://struts.apache.org/2.x/docs/email-validator.html
		pat = Pattern.compile("\\b(^[_A-Za-z0-9-](\\.[_A-Za-z0-9-])*@([A-Za-z0-9-])+((\\.com)|(\\.net)|(\\.org)|(\\.info)|(\\.edu)|(\\.mil)|(\\.gov)|(\\.biz)|(\\.ws)|(\\.us)|(\\.tv)|(\\.cc)|(\\.aero)|(\\.arpa)|(\\.coop)|(\\.int)|(\\.jobs)|(\\.museum)|(\\.name)|(\\.pro)|(\\.travel)|(\\.nato)|(\\..{2,3})|(\\..{2,3}\\..{2,3}))$)\\b");
		mat = pat.matcher(eMail);
		if (mat.find()) {
			logger.debug("[" + mat.group() + "]");
			return true;
		}else{
			return false;
		}        
	}

	/**
	 * Determina si un porcentaje esta entre 0 y 100.
	 * @param porcentgeMontoCnto
	 * @return true, si el porcentaje esta entre 0 y 100
	 */
	public static boolean isPercentValid(Float porcentgeMontoCnto){

		return porcentgeMontoCnto<100.0 && porcentgeMontoCnto>0.0;

	}
	
	/**
	 * Determina si el argumente tiene un largo mayor o igual a 3 caracteres.
	 * @param aVerificar el valor a verificar
	 * @return true, si el argumento tiene mas de 2 caracteres.
	 */
	public static Boolean esLargoMayorIgualQueTres(String aVerificar){
		if(isEmpty(aVerificar)){
			return true;
		}
		
		return aVerificar.length()>2;
		
	}
	
	/**
	 * Lanza una excepcion del tipo {@link IllegalArgumentException} en caso que el argumento <pre>o</pre> sea nulo.
	 * @param o el objeto a verificar
	 */
	public static void verificaNulo(Object o){
		verificaNulo(o, "El argumento es nulo.");
	}
	
	/**
	 * Lanza una excepcion del tipo {@link IllegalArgumentException} en caso que el argumento <pre>o</pre> sea nulo.
	 * @param o el objeto a verificar
	 * @param mensaje Mensaje de error a mostrar.
	 */
	public static void verificaNulo(Object o, String mensaje){
		if(isNull(o)){
			throw new IllegalArgumentException(mensaje);
		}
	}
	
	public static void main(String [] args){
		Boolean x = true;
		System.out.println("x = true -> " + x);
		System.out.println("x &= true -> " +( x &= true ));
		System.out.println("x &= false -> " +( x &= false ));
		
		System.out.println("x = false -> " + x);
		System.out.println("x &= false -> " +( x &= false ));
		System.out.println("x &= true -> " +( x &= true ));
	}
}
